package io.hilo.example.app.redis;

import java.net.UnknownHostException;

import org.hilo.boot.app.config.RedisConfig;
import org.hilo.boot.core.redis.AbstractRedisConfig;
import org.hilo.boot.core.redis.LettuceConnectionConfiguration;
import org.hilo.boot.core.redis.RedisTemplateConfiguration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import io.lettuce.core.resource.ClientResources;

/**
 * 多Redis源示例（配置一对RedisProperties和RedisConnectionFactory）
 * 
 * @author zollty
 * @since 2018年6月26日
 */
//@Configuration // 此为示例，需要时启用
@ConditionalOnProperty(RedisConfig.NAMES)
public class RedisConfigFoo2 extends AbstractRedisConfig {

    // 示例Redis源的name为 foo2，注意后缀
    @Bean
    @ConfigurationProperties(RedisConfig.PREFIX + "foo2")
    public RedisProperties redisPropertiesFoo2() {
        return new RedisProperties();
    }
    
    // jedis用法（不建议使用，建议使用Lettuce）
//    @Bean
//    public JedisConnectionFactory redisConnectionFactoryFoo2(
//            @Qualifier("redisProperties" + "Foo2") 
//            RedisProperties properties, 
//            ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
//            ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
//            ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) throws UnknownHostException {
//        return new JedisConnectionConfiguration(properties, sentinelConfiguration.getIfAvailable(), 
//                clusterConfiguration.getIfAvailable(), builderCustomizers).redisConnectionFactory();
//    }
    
    // Lettuce用法
    @Bean
    @ConditionalOnMissingBean(RedisConnectionFactory.class)
    public LettuceConnectionFactory redisConnectionFactory(
            @Qualifier("redisProperties" + "Foo2") 
            RedisProperties properties,
            ObjectProvider<RedisSentinelConfiguration> sentinelConfiguration,
            ObjectProvider<RedisClusterConfiguration> clusterConfiguration,
            ClientResources clientResources, 
            ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers) throws UnknownHostException {
        return new LettuceConnectionConfiguration(properties,
                sentinelConfiguration.getIfAvailable(), clusterConfiguration.getIfAvailable(),
                builderCustomizers).redisConnectionFactory(clientResources);
    }
    
    /**
     * RedisTemplate configuration.
     */
    @Configuration
    @ConditionalOnBean(name = "redisConnectionFactory" + "Foo2")
    static class TemplateConfig extends RedisTemplateConfiguration {

        public TemplateConfig(
                @Qualifier("redisConnectionFactory" + "Foo2") 
                RedisConnectionFactory connectionFactory) {
            super(connectionFactory);
        }
        
        @Bean
        public RedisTemplate<Object, Object> redisTemplateFoo2() {
            RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
            template.setConnectionFactory(connectionFactory);
            return template;
        }

    }

}
